#ifndef _SLAB_H
#define _SLAB_H

#include <ds/list.h>
#include <type.h>

#define CACHE_NAME_LEN 16

#define ALIGN_DMA 1

typedef struct {
    lnode_t caches;
    lnode_t full;
    lnode_t used;
    lnode_t free;
    size_t offset;
    size_t obj_size;
    size_t slab_count;
    size_t used_count;
    long obj_per_slab;
    size_t page_per_cache;
    char cache_name[CACHE_NAME_LEN];
} kmem_cache_t;

typedef long obj_idx_t;

typedef struct {
    lnode_t slabs;
    void* first_obj;
    size_t used_objs;
    long next_free;
    obj_idx_t free_list[0];
} slab_t;

kmem_cache_t* new_kmem_cache(char* name, size_t obj_size, size_t page_per_cache, int opt);

void* take_obj(kmem_cache_t* cache);

int release_obj(kmem_cache_t* cache, void* obj);

void kmem_cache_init();

void kmem_cache_show_status();

#endif /* _SLAB_H */